from .common import *
import base64,oss2
def index():
    if sysisphone():
        return response.tpl("../tplm/setup/index")
    else:
        return response.tpl()
def basepage():
    "基本配置"
    if sysisphone():
        return response.tpl("../tplm/setup/basepage")
    else:
        return response.tpl()
def startpage():
    "开机启动项"
    if sysisphone():
        return response.tpl("../tplm/setup/startpage")
    else:
        return response.tpl()
def bacrecpage():
    "备份恢复页面"
    if sysisphone():
        return response.tpl("../tplm/setup/bacrecpage")
    else:
        return response.tpl()
def pythonrun():
    "项目管理器"
    if sysisphone():
        return response.tpl("../tplm/setup/pythonrun")
    else:
        return response.tpl()
def restart(types='stop'):
    "启动/停止项目管理"
    G.setadminlog="启动/停止项目管理"
    data=request.get_json()
    interpreter=md5(data['paths']+data['types']+data['filename']+data['other']) #解释器
    if types=='start':
        if data['types']=='python3.6':
            if not os.path.isfile("/usr/bin/"+interpreter):
                os.system("ln -s /usr/local/python/python3.6/bin/python3 /usr/bin/"+interpreter)
        elif data['types']=='php7.2':
            if os.path.isfile("/usr/local/php/php7.2/bin/php"):
                os.system("ln -s /usr/local/php/php7.2/bin/php /usr/bin/"+interpreter)
            else:
                return errorjson(msg="您必须使用本系统的软件插件安装php7.2后才能使用该功能")
        elif data['types']=='php7.3':
            if os.path.isfile("/usr/local/php/php7.3/bin/php"):
                os.system("ln -s /usr/local/php/php7.3/bin/php /usr/bin/"+interpreter)
            else:
                return errorjson(msg="您必须使用本系统的软件插件安装php7.3后才能使用该功能")
        if data['other']: #带运行参数
            os.system("cd "+data['paths']+"&& nohup "+interpreter+" "+data['filename']+" "+data['other']+"  > "+data['paths']+"/"+interpreter+".log 2>&1 &")
        else:
            os.system("cd "+data['paths']+"&& nohup "+interpreter+" "+data['filename']+"  > "+interpreter+".log 2>&1 &")
        time.sleep(1)
        if get_process_id(interpreter):
            return successjson()
        else:
            return errorjson(msg="启动失败")
    elif types=='stop':
        os.system("pkill -9 "+interpreter[:12])
        return successjson()
def setpythonrun():
    "设置/添加项目管理"
    G.setadminlog="设置/添加项目管理"
    if 'Linux' in get_sysinfo()['platform']:
        data=request.get_json()
        
        interpreter=md5(data['paths']+data['types']+data['filename']+data['other']) #解释器
        if not os.path.isfile("/usr/bin/"+interpreter):
            if data['types']=='python3.6':
                os.system("ln -s /usr/local/python/python3.6/bin/python3 /usr/bin/"+interpreter)
            elif data['types']=='php7.2':
                if os.path.isfile("/usr/local/php/php7.2/bin/php"):
                    os.system("ln -s /usr/local/php/php7.2/bin/php /usr/bin/"+interpreter)
                else:
                    return errorjson(msg="您必须使用本系统的软件插件安装php7.2后才能使用该功能")
            elif data['types']=='php7.3':
                if os.path.isfile("/usr/local/php/php7.3/bin/php"):
                    os.system("ln -s /usr/local/php/php7.3/bin/php /usr/bin/"+interpreter)
                else:
                    return errorjson(msg="您必须使用本系统的软件插件安装php7.3后才能使用该功能")
        if data['other']: #带运行参数
            os.system("cd "+data['paths']+"&& nohup "+interpreter+" "+data['filename']+" "+data['other']+"  > "+data['paths']+"/"+interpreter+".log 2>&1 &")
        else:
            os.system("cd "+data['paths']+"&& nohup "+interpreter+" "+data['filename']+"  > "+data['paths']+"/"+interpreter+".log 2>&1 &")
        time.sleep(1)
        if get_process_id(interpreter):
            if data['id']:
                arr=sqlite("pythonrun").where("id",data['id']).find()
                interpreterj=md5(arr['paths']+arr['types']+arr['filename']+arr['other']) #解释器
                if interpreterj!=interpreter:#删除之前的
                    os.system("pkill -9 "+interpreterj[:12])
                    os.remove("/usr/bin/"+interpreterj)
                data.update(updtime=times(),addtime=times())
                del data['status']
                sqlite("pythonrun").where("id",data['id']).update(data)
                return successjson()
            else:
                del data['id']
                data.update(updtime=times(),addtime=times())
                sqlite("pythonrun").insert(data)
                return successjson()
        else:
            return errorjson(interpreter)
    else:
        return errorjson(msg="不支持该系统，当前只支持linux")
def logpythonrun(id):
    "项目管理日志"
    G.setadminlog="项目管理日志"
    arr=sqlite("pythonrun").where('id',id).find()
    interpreter=md5(arr['paths']+arr['types']+arr['filename']+arr['other']) #解释器
    data=file_get_content(arr['paths']+"/"+interpreter+".log")
    return successjson(data)
def delpythonrun(id=''):
    "删除项目管理"
    G.setadminlog="删除项目管理"
    try:
        if id:
            id=[id]
        else:
            id=request.get_json()
        arr=sqlite("pythonrun").where('id','in',id).field("paths,types,filename,other").select()
        for k in arr:
            interpreter=md5(k['paths']+k['types']+k['filename']+k['other']) #解释器
            os.system("pkill -9 "+interpreter[:12])
            if os.path.isfile("/usr/bin/"+interpreter):
                os.remove("/usr/bin/"+interpreter)
        sqlite("pythonrun").where('id','in',id).delete()
    except:
        return errorjson(msg="失败")
    else:
        return successjson()
def pythonrulists(id=''):
    "项目管理列表"
    if id:
        return successjson(sqlite("pythonrun").find(id))
    where=None
    kw=request.args.get('kw')
    pagenow=request.args.get('pagenow')
    pagesize=request.args.get('pagesize')
    if kw:
        where=[("title","like","%"+str(kw)+"%"),'or',("descs","like","%"+str(kw)+"%")]
    if not pagenow:
        pagenow=1
    else:
        pagenow=int(pagenow)
    if not pagesize:
        pagesize=10
    else:
        pagesize=int(pagesize)
    lists=sqlite("pythonrun").where(where).page(pagenow,pagesize).select()
    for k in lists:
        interpreter=md5(k['paths']+k['types']+k['filename']+k['other']) #解释器
        if get_process_id(interpreter):
            k['status']=1 #运行中
        else:
            k['status']=0 #已停止
    count=sqlite("pythonrun").where(where).count()
    data=return_list(lists,count,pagenow,pagesize)
    return successjson(data)
def setbaseconfig(types='get'):
    "保存配置信息"
    
    if types=='get':
        if os.path.isfile("app/common/file/config.conf"):
            data=json_decode(file_get_content("app/common/file/config.conf"))
            if not data['aliyun']['backpath']:
                data['aliyun']['backpath']="kcweb"
        else:
            data={}
        return successjson(data)
    else:
        G.setadminlog="保存配置信息"
        config=request.get_json()
        file_set_content("app/common/file/config.conf",json_encode(config))
        return successjson(msg="保存成功")

def addstart():
    "添加启动项"
    G.setadminlog="添加启动项"
    data=request.get_json()
    if sqlite("start").connect(model_app_path).where("value",data['value']).count():
        return errorjson(msg="禁止重复添加")
    try:
        icon=data['icon']
    except:
        icon=''
    if system_start.insert_Boot_up(cmd=data['value'],name=data['name'],types=data['types'],admin_id=G.userinfo['id'],icon=icon):
        return successjson()
    else:
        return errorjson(msg="添加失败，该系统支不支持")
def delstart():
    G.setadminlog="删除启动项"
    data=request.get_json()
    if system_start.del_Boot_up(cmd=data['value'],id=data['id']):
        return successjson()
    else:
        return errorjson()
def startlist():
    "启动项列表"
    pagenow=request.args.get('pagenow')
    pagesize=request.args.get('pagesize')
    if not pagenow:
        pagenow=1
    else:
        pagenow=int(pagenow)
    if not pagesize:
        pagesize=100
    else:
        pagesize=int(pagesize)
    yz=system_start.lists(pagenow,pagesize)
    lists=yz[0]
    count=yz[1]
    data=return_list(lists,count,pagenow,pagesize)
    
    return successjson(data)

def aliyunosslist(types='app'):
    if not os.path.isfile("app/common/file/config.conf"):
        return errorjson(msg="请先配置阿里云oss配置信息")
    data=json_decode(file_get_content("app/common/file/config.conf"))
    prefix=request.args.get("prefix")
    if not prefix:
        if types=='app':
            prefix="backups/"+data['aliyun']['backpath']+"/app/"
        else:
            prefix="backups/"+data['aliyun']['backpath']+"/backup/mysql/"
    data=[]
    try:
        fileconfig=json_decode(file_get_content("app/common/file/config.conf"))
        auth = oss2.Auth(fileconfig['aliyun']['access_key'],fileconfig['aliyun']['access_key_secret'])
        bucket = oss2.Bucket(auth,fileconfig['aliyun']['address'],fileconfig['aliyun']['bucket'])
        # 列举fun文件夹下的文件与子文件夹名称，不列举子文件夹下的文件。
        
        for obj in oss2.ObjectIterator(bucket, prefix = prefix, delimiter = '/'):
            # 通过is_prefix方法判断obj是否为文件夹。
            if obj.is_prefix():  # 文件夹
                data.insert(0,{"name":obj.key.split("/")[-2],"path":obj.key,"type":"folder"})
            else:                # 文件
                data.insert(0,{"name":obj.key.split("/")[-1],"path":obj.key,"type":"file"})
    except:pass
    # data1=[]
    # i=len(data)
    # while True:
    #     i+=1
    #     if i<0:
    #         break
    #     else:
    #         data1.append(data[i])
    return successjson(data)
def aliyunossdownload(types=""):
    "从阿里云备份点恢复"
    if not os.path.isfile("app/common/file/config.conf"):
        return errorjson(msg="请先配置阿里云oss配置信息")
    fileconfig=json_decode(file_get_content("app/common/file/config.conf"))
    auth = oss2.Auth(fileconfig['aliyun']['access_key'],fileconfig['aliyun']['access_key_secret'])
    bucket = oss2.Bucket(auth,fileconfig['aliyun']['address'],fileconfig['aliyun']['bucket'])
    filepath=request.args.get("filepath")
    if types=='mysql': #恢复mysql
        pass
    else: #恢复文稿
        bucket.get_object_to_file(filepath, "backup.zip")
        zip.unzip_file("backup.zip","backup/app")
        os.remove("backup.zip")
        if os.path.exists("backup/app"):
            filelist=get_file("backup/app")
            for k in filelist:
                if k['type']=='folder' and '__pycache__' not in k['path']:
                    if 'common/file' == k['path'][-11:]:
                        path=re.sub("backup/","",k['path'])
                        if os.path.exists(path):
                            shutil.rmtree(path)
                        shutil.copytree(k['path'],path)
    return successjson()
def backup(types=''):
    "备份全部"
    G.setadminlog="备份全部"
    paths=request.args.get("paths")
    if paths: #备份目录  app/common/file
        shutil.copytree(paths,"backup/"+paths)
    else: #备份全部
        filelist=get_file("app")
        if os.path.exists("backup"):
            shutil.rmtree("backup")
        for k in filelist:
            if k['type']=='folder' and '__pycache__' not in k['path']:
                if 'common/file' == k['path'][-11:]:
                    shutil.copytree(k['path'],"backup/"+k['path'])
                    # print(k['path'],"backup/"+k['path'])
    if types=='aliyun':#备份文件上传到阿里云oss
        if not os.path.isfile("app/common/file/config.conf"):
            print("您没有保存阿里云oss修改配置信息而无法上传")
        else:
            fileconfig=json_decode(file_get_content("app/common/file/config.conf"))
            backpath=fileconfig['aliyun']['backpath']
            if backpath:
                if backpath[:1]=='/':
                    backpath=backpath[1:]
                if backpath[-1]=='/':
                    backpath=backpath[:-1]
            else:
                backpath="kcweb"
            auth = oss2.Auth(fileconfig['aliyun']['access_key'],fileconfig['aliyun']['access_key_secret'])
            bucket = oss2.Bucket(auth,fileconfig['aliyun']['address'],fileconfig['aliyun']['bucket'])
            zip.packzip("backup/app","backup/app.zip")
            oss2.resumable_upload(bucket,"backups/"+backpath+"/app/"+time.strftime("%Y%m%d-%H:%M:%S",time.localtime(times()))+".zip","backup/app.zip")
            filelist=[]
            for obj in oss2.ObjectIterator(bucket, prefix="backups/"+backpath+"/app/"):
                filelist.append(obj.key)
            i=0
            while True:
                if len(filelist)-i <= 30: #在阿里云保留30个备份文件
                    break
                bucket.delete_object(filelist[i])
                i+=1
            os.remove("backup/app.zip")
            print("上传到阿里云oss成功")
    if not config.app['cli']:
        return successjson(msg="所有文稿备份成功")
def recovery():
    "恢复文稿"
    G.setadminlog="恢复文稿"
    paths=request.args.get("paths")
    if paths: #恢复指定目录 app/common/file
        shutil.copytree("backup/"+paths,paths)
    elif os.path.exists("backup/app"): #恢复全部文稿
        filelist=get_file("backup/app")
        for k in filelist:
            if k['type']=='folder' and '__pycache__' not in k['path']:
                if 'common/file' == k['path'][-11:]:
                    path=re.sub("backup/","",k['path'])
                    if os.path.exists(path):
                        shutil.rmtree(path)
                    shutil.copytree(k['path'],path)
                    print(k['path'],path)
        return successjson(msg="所有文稿恢复成功")
    else:
        return errorjson(msg="备份目录不存在")
def download(name=""):
    "下载备份文件"
    G.setadminlog="下载备份文件"
    if os.path.exists("backup"):
        zip.packzip("backup","backup.zip")
        f=open("backup.zip","rb")
        body=f.read()
        f.close()
        os.remove("backup.zip")
        return body,"200 ok",{"Content-Type":"application/zip","Accept-Ranges":"bytes"}
    else:
        return "没有备份文件，请备份文件后再下载"
def postsup():
    "上传备份文件"
    G.setadminlog="上传备份文件"
    if request.binary.save('file',"backup."+request.binary.filesuffix('file')):
        zip.unzip_file("backup.zip","backup")
        os.remove("backup.zip")
        return successjson()
    else:
        return errorjson(msg="上传失败")
def dowfile(name=''):
    "下载指定文件"
    G.setadminlog="下载指定文件"
    pathname=request.args.get("pathname")
    return response.download(pathname)
def uploadfile():
    "上传文件导指定目录"
    G.setadminlog="上传文件导指定目录"
    pathname=request.args.get("pathname")
    if request.binary.save('file',pathname):
        return successjson()
    else:
        return errorjson(msg="上传失败")
def backxz(name=''):
    "压缩指定文件夹并下载"
    G.setadminlog="压缩指定文件夹并下载"
    paths=request.args.get("paths")
    zip.packzip(paths,"backxz.zip")
    f=open("backxz.zip","rb")
    body=f.read()
    f.close()
    os.remove("backxz.zip")
    return body,"200 ok",{"Content-Type":"application/zip","Accept-Ranges":"bytes"}
def upunback():
    "上传zip压缩包并解压指定文件夹"
    G.setadminlog="上传zip压缩包并解压指定文件夹"
    paths=request.args.get("paths")
    if request.binary.save('file',"backxz."+request.binary.filesuffix('file')):
        try:
            zip.unzip_file("backxz.zip",paths)
            os.remove("backxz.zip")
        except:
            return errorjson(msg="文件格式错误")
        return successjson()
    else:
        return errorjson(msg="上传失败")
    return successjson()
